#include "TcpServer.hpp"
#include <memory>
#include "Protocal.hpp"
#include "Calculator.hpp"
#include "LVProtocol.hpp"
// #include "Daemon.hpp"

using Cal_t = std::function<response(const request &req)>;          // 传一个请求，返回一个resp结构化数据
using Cal_Add = std::function<Json::Value(const Json::Value &req)>; // 传一个请求，返回一个resp结构化数据
// 处理模块
class Parse
{
public:
    Parse(Cal_t cal) : _cal(cal)
    {
    }
    std::string Entry(std::string &package)
    {
        std::string message;
        std::string respstr;
        while (Decode(package, &message)) // 前面的都是用来判断的，最后的body(Json::Value处理的那块)才是需要关心的
        {

            LOG(LogLevel::DEBUG) << "Content: \n"
                                 << message;
            /*if (message.empty())
                break;*/

            // 2. 反序列化， message是一个曾经被序列化的request
            request req;
            /*if (!req.Deserialize(message))
                break*/
            req.Deserialize(message);

            std::cout << "#############" << std::endl;
            req.Print();
            std::cout << "#############" << std::endl;

            // 3. 计算
            response resp = _cal(req);

            // 4. 序列化
            std::string res;
            resp.Serialize(res);
            LOG(LogLevel::DEBUG) << "序列化: \n"
                                 << res;

            // 5. 添加长度报头字段！
            Encode(res);

            LOG(LogLevel::DEBUG) << "Encode: \n"
                                 << res;

            // 6. 拼接应答
            respstr += res;
        }
        LOG(LogLevel::DEBUG) << "respstr: \n"
                             << respstr;
        return respstr;
    }
    ~Parse()
    {
    }

private:
    Cal_t _cal;
};

class LVProtocol_parse2
{
public:
    LVProtocol_parse2(Cal_Add cal) : _cal(cal)
    {
    }

    std::string Entry(std::string &package)
    {
        // 拿进来一个packge
        // 1.进行反序列化
        std::cout << "到这了Entry" << std::endl;

        // 打印package的大小，但不尝试打印package的内容，因为可能包含二进制数据
        std::cout << "package.size(): " << package.size() << std::endl;

        // 创建一个具体的请求对象
        std::shared_ptr<zj::BaseMessage> msg = std::make_shared<zj::NetCalRequest>();
        std::string respstr;

        // 添加循环次数限制，防止无限循环
        int max_loops = 100; // 防止无限循环
        int loop_count = 0;

        while (loop_count < max_loops)
        {
            // 检查Decode结果
            if (!zj::LVProtocol::Decode(package, msg))
            {
                std::cout << "Decode失败，退出当前循环" << std::endl;
                break;
            }

            loop_count++;
            std::cout << "到这了Entry1, 循环次数: " << loop_count << std::endl;

            // 此时msg内部有数据
            zj::MType mtype = msg->mtype();
            std::cout << "消息类型: " << static_cast<int>(mtype) << std::endl;
            std::cout << "ADD_REQUEST类型值: " << static_cast<int>(zj::MType::ADD_REQUEST) << std::endl;

            // 检查消息类型
            if (mtype != zj::MType::ADD_REQUEST)
            {
                std::cout << "消息类型错误: 期望ADD_REQUEST(" << static_cast<int>(zj::MType::ADD_REQUEST)
                          << "), 实际得到(" << static_cast<int>(mtype) << ")" << std::endl;
                return std::string("");
            }

            // 动态类型转换，确保类型正确
            auto type_msg = std::dynamic_pointer_cast<zj::NetCalRequest>(msg);
            if (!type_msg)
            {
                std::cout << "动态类型转换失败，无法转换为NetCalRequest" << std::endl;
                return std::string("");
            }

            // 检查消息是否有效
            if (!type_msg->check())
            {
                std::cout << "NetCalRequest消息检查失败" << std::endl;
                return std::string("");
            }

            try
            {
                Json::Value parms = type_msg->parms();
                std::cout << "成功获取参数" << std::endl;
                /*std::string req1;
                zj::JsonAPI::serialize(parms, &req1);
                std::cout << req1 << std::endl;
                std::cout << "OPER值: " << parms["OPER"].asInt() << std::endl;*/
                // 获得结果的parms
                Json::Value result_parms = _cal(parms);

                std::shared_ptr<zj::NetCalResponse> msg_result = std::make_shared<zj::NetCalResponse>();
                std::string id = zj::UUID::uuid();
                msg_result->setId(id);
                msg_result->setMType(zj::MType::ADD_RESPONSE);

                if (result_parms.isMember("RCODE"))
                {
                    msg_result->setRCode(static_cast<zj::RCode>(result_parms["RCODE"].asInt()));
                }

                if (result_parms.isMember("RESULT"))
                {
                    msg_result->setresult(static_cast<u_int32_t>(result_parms["RESULT"].asInt()));
                }

                std::string ss = zj::LVProtocol::Encode(msg_result);
                std::cout << "编码后的响应长度: " << ss.size() << std::endl;
                respstr += ss;
                
                // 为下一次循环重新创建一个新的消息对象
                msg = std::make_shared<zj::NetCalRequest>();
            }
            catch (const std::exception &e)
            {
                std::cout << "处理请求时发生异常: " << e.what() << std::endl;
                return std::string("");
            }
        }

        // 检查是否达到最大循环次数
        if (loop_count >= max_loops)
        {
            std::cout << "达到最大循环次数，防止无限循环" << std::endl;
        }

        std::cout << "Entry方法结束，respstr大小: " << respstr.size() << std::endl;
        std::cout << "Entry方法结束，respstr: " << respstr << std::endl;
        return respstr;
    }

    ~LVProtocol_parse2()
    {
    }

private:
    Cal_Add _cal;
};

int main(int argc, char *argv[])
{
    // ENABLE_FILE_LOG();
    // Daemon(false,false);

    Calculator cal;
    LVProtocol_parse2 parse([&cal](const Json::Value &req)
                            { return cal.Execute(req); });

    int server_port = std::stoi(argv[1]);
    // Command com;
    /*std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>([&parse](std::string &package)
                                                                  { return parse.Entry(package); }, server_port);*/
    std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>([&parse](std::string &package)
                                                                  { return parse.Entry(package); }, server_port);
    tsvr->InitServer();
    tsvr->Start();

    /*request req(10, 20, '+');
    std::string ss;
    req.Serialize(ss);

    std::cout << ss << std::endl;*/

    return 0;
}
